let prefix = '';
const handleKey = (key: string) => `${prefix}_${key}`;

function setPrefix(value: string) {
  prefix = value;
}

function getStorage(local: boolean = true) {
  return local ? window.localStorage : window.sessionStorage;
}

function set(key: string, value: any, local: boolean = true) {
  if (key && value) {
    try {
      let valueString;
      if (value instanceof Array || value instanceof Object) {
        valueString = JSON.stringify(value);
      } else {
        valueString = value;
      }
      getStorage(local).setItem(handleKey(key), valueString);
      return true;
    } catch (e) {
      return false;
    }
  } else {
    return false;
  }
}

function get(key: string, local: boolean = true) {
  if (key) {
    let value: any = null;
    try {
      const valueString: any = getStorage(local).getItem(handleKey(key));
      value = valueString;
      const firstChar = valueString && valueString.length > 1 ? valueString.charAt(0) : null;
      if (firstChar === '{' || firstChar === '[') {
        return JSON.parse(valueString);
      }
      return valueString;
    } catch (e) {
      return value;
    }
  } else {
    return null;
  }
}

function remove(key: string, local: boolean = true) {
  return getStorage(local).removeItem(handleKey(key));
}

function setAsync(key: string, value: any, local: boolean = true) {
  return new Promise((resolve) => {
    resolve(set(key, value, local));
  });
}

function getAsync(key: string, local: boolean = true) {
  return new Promise((resolve) => {
    resolve(get(key, local));
  });
}

function removeAsync(key: string, local: boolean = true) {
  return new Promise((resolve) => {
    resolve(getStorage(local).removeItem(handleKey(key)));
  });
}

export { setPrefix, set, get, remove, setAsync, getAsync, removeAsync };
export default { setPrefix, set, get, remove, setAsync, getAsync, removeAsync };
